package com.gitee.sparta.core.cluster.strategy;

import com.gitee.sparta.core.bean.cluster.ClusterProtocol;
import com.gitee.sparta.core.bean.cluster.ServerBean;
import com.gitee.sparta.core.cluster.ClusterCache;
import com.gitee.sparta.core.cluster.balance.LoadBalance;
import com.gitee.sparta.core.property.SpartaCoreProperties;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;

import java.nio.channels.SocketChannel;

/**
 * <p>
 *      follower 连接上 leader，leader 给 follower 分配 id
 * </p>
 *
 * @author zyred
 * @since v 0.0.2
 */
@Slf4j
public class FollowerAcceptedStrategy extends Strategy {

    /**
     * 是否启动心跳线程
     **/
    private volatile boolean enableHeartbeat;

    public FollowerAcceptedStrategy(RedissonClient client,
                                    LoadBalance loadBalance,
                                    SpartaCoreProperties properties) {
        super(client, loadBalance, properties);
        this.enableHeartbeat = false;
    }

    @Override
    public void handle(ChannelHandlerContext ctx, SocketChannel sc, ClusterProtocol cp) {
        log.info("[Sparta] Accept leader response, myId: {}, leaderId : {}",
                cp.getServerId(), cp.getLeaderSid());

        RMap<Integer, ServerBean> serverTable = super.client.getMap(super.properties.getServerTable());
        ServerBean selfBean = serverTable.get(cp.getServerId());
        serverTable.remove(cp.getServerId());
        serverTable.put(cp.getServerId(), selfBean);

        this.properties.setIsolation(selfBean.getIsolation());

        ClusterCache.setServerId(cp.getServerId());
        ClusterCache.setLeaderSid(cp.getLeaderSid());
        ClusterCache.putServerInfo(cp.getServerId(), selfBean);

        if (ClusterCache.isNetty()) {
            ClusterCache.putClient(ctx.channel(), cp.getServerId());
        } else {
            ClusterCache.putClient(sc, cp.getServerId());
            if (!enableHeartbeat) {
                new FollowerNioHeartbeatStrategy(this.properties, sc, cp.getServerId());
                enableHeartbeat = true;
            }
        }
    }
}
